home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Mania 5
/
MacMania 5.toast
/
/
Internet software
/
NewsWatcher
/
NW Source
/
Source
/
prefs.c
< prev
next >
Wrap
Text File
|
1997-01-09
|
49KB
|
1,640 lines
/*----------------------------------------------------------------------------
prefs.c
This module handles locating, reading, and writing the prefs file, and
initialization of the preferences if no prefs file exists or an old
version is encountered.
Copyright © 1994-1997, Northwestern University.
----------------------------------------------------------------------------*/
#include <string.h>
#include <stdio.h>
#include "glob.h"
#include "prefs.h"
#include "dialog.h"
#include "full.h"
#include "newswatcher.h"
#include "drawutil.h"
#include "strutil.h"
#include "memutil.h"
#include "cache.h"
#include "apputil.h"
#include "wind.h"
#include "fileutil.h"
#include "resutil.h"
#include "menus.h"
#include "sfutil.h"
#include "url.h"
#include "ic.h"
#include "print.h"
#include "header.h"
#define kNewUserDlg 158 /* New user dialog */
#define kNewUserPrivateItem 1
#define kNewUserSharedItem 2
#define kNewUserLabItem 3
#define kNewUserQuitItem 4
#define kGetFloppyDlg 159 /* Get floppy dialog */
#define kGetFloppyCancelItem 1
#define kEraseFloppyDlg 160 /* Erase floppy dialog */
#define kEraseFloppyCancelItem 2
#define kWaitEraseDlg 161 /* Wait for floppy erase dialog */
#define kServerDlg 132 /* Server dialog */
#define kNewsServer 6
#define kMailServer 8
#define kPersonalDlg 138 /* Personal info dialog */
#define kFullName 6
#define kOrganization 8
#define kAddress 10
#define kNew20UserAlert 146
#define kSavedMsgDefaultFolderAliasID 128 /* 'alis' resource id for saved message
default folder alias */
#define kSavedArtDefaultFolderAliasID 129 /* 'alis' resource id for saved article
default folder alias */
#define ksavedBinDefaultFolderAliasID 130 /* 'alis' resource id for extracting
binaries download folder alias */
#define ksavedUGLDefaultFolderAliasID 131 /* 'alis' resource id for saved user
group list folder alias */
#define kURLHelpersType 'URLH' /* rsrc type for URL helpers */
#define kURLHelpersID 128 /* rsrc id for URL helpers */
static AliasHandle gPrefsAlias = nil; /* handle to alias to prefs file, or
nil if prefs file not found */
static Boolean gPrefsFileWasOldVersion = false;
/* true if prefs file was old version */
static Str255 gNewsServerAtStartup; /* news server address at startup */
static Boolean gDummyPrefsFile = false; /* true if dummy prefs file found */
static Boolean gDummyPrefsLabFile = false; /* true if dummy prefs file contains "lab" */
static Boolean gFloppyWasFormatted; /* true if floppy was formatted on insertion */
/*----------------------------------------------------------------------------
MakeDefaultFolderAlias
Initialize the alias for a default folder preference to the desktop
folder on the startup volume.
Entry: *alias = handle to previous alias if any, else nil.
Exit: *alias = handle to new alias.
----------------------------------------------------------------------------*/
static void MakeDefaultFolderAlias (AliasHandle *alias)
{
OSErr err = noErr;
FSSpec fSpec;
CInfoPBRec pBlock;
if (*alias != nil) {
MyDisposeHandle(*alias);
*alias = nil;
}
err = FindFolder(kOnSystemDisk, kDesktopFolderType, false,
&pBlock.dirInfo.ioVRefNum, &pBlock.dirInfo.ioDrDirID);
if (err != noErr) return;
pBlock.dirInfo.ioNamePtr = fSpec.name;
pBlock.dirInfo.ioFDirIndex = -1;
err = PBGetCatInfoSync(&pBlock);
if (err != noErr) return;
fSpec.vRefNum = pBlock.dirInfo.ioVRefNum;
fSpec.parID = pBlock.dirInfo.ioDrParID;
NewAlias(nil, &fSpec, alias);
}
/*----------------------------------------------------------------------------
GetFloppyDialogFilter
Filter proc for the get floppy dialog.
Entry: dlg = pointer to dialog.
ev = pointer to event record.
Exit: function result = true if event handled and item hit.
*itemHit = item number of item hit.
ev = pointer to possibly modified event record.
When a floppy is inserted, *itemHit is set to the negative of the drive
number of the inserted floppy, and the function returns true. In addition,
the global variable gFloppyWasFormatted is set to true if the floppy was
formatted.
----------------------------------------------------------------------------*/
static pascal Boolean GetFloppyDialogFilter (DialogPtr dlg, EventRecord *ev,
short *itemHit)
{
Point thisPoint;
OSErr err = noErr;
if (ev->what == diskEvt) {
if ((ev->message & 0xffff0000) != 0) {
DILoad();
SetPt(&thisPoint, 120, 120);
err = DIBadMount(thisPoint, ev->message);
DIUnload();
if (err != noErr) return err;
gFloppyWasFormatted = true;
}
*itemHit = -(ev->message & 0xffff);
return true;
}
return DialogFilter(dlg, ev, itemHit);
}
/*----------------------------------------------------------------------------
DoGetFloppyDialog
Present the get floppy dialog.
Exit: function result = error code.
*vRefNum = vol ref num of inserted floppy.
name = vol name.
----------------------------------------------------------------------------*/
static OSErr DoGetFloppyDialog (short *vRefNum, StringPtr name)
{
DialogPtr dlg = nil;
short item, drvNum;
long freeBytes;
HParamBlockRec pBlock;
OSErr err = noErr;
UnmountVol(nil, 1);
Eject(nil, 1);
UnmountVol(nil, 2);
Eject(nil, 2);
while (true) {
gFloppyWasFormatted = false;
err = MyGetNewDialog(kGetFloppyDlg, 0, kGetFloppyCancelItem, &dlg);
if (err != noErr) return err;
MyMovableModalDialog(dlg, GetFloppyDialogFilter, &item);
err = DoClose(dlg);
if (err != noErr) return err;
if (item == kGetFloppyCancelItem) return userCanceledErr;
drvNum = -item;
err = GetVInfo(drvNum, name, vRefNum, &freeBytes);
if (err != noErr) return err;
pBlock.volumeParam.ioNamePtr = name;
pBlock.volumeParam.ioVRefNum = drvNum;
pBlock.volumeParam.ioVolIndex = 0;
err = PBHGetVInfoSync(&pBlock);
if (err != noErr) return err;
if ((pBlock.volumeParam.ioVAtrb >> 7) & 1) {
UnmountVol(nil, drvNum);
Eject(nil, drvNum);
ErrorMessageNumber(kStrFloppyLocked);
continue;
}
if (!gFloppyWasFormatted) {
err = MyGetNewDialog(kEraseFloppyDlg, kEraseFloppyCancelItem,
kEraseFloppyCancelItem, &dlg);
ParamText(name, "\p", "\p", "\p");
if (err != noErr) return err;
MyMovableModalDialog(dlg, DialogFilter, &item);
err = DoClose(dlg);
if (err != noErr) return err;
if (item == kEraseFloppyCancelItem) {
UnmountVol(nil, drvNum);
Eject(nil, drvNum);
continue;
}
err = MyGetNewDialog(kWaitEraseDlg, 0, 0, &dlg);
if (err != noErr) return err;
SetCursor(&gWatchCurs);
MyShowWindow(dlg);
HandleUpdate(dlg);
err = UnmountVol(nil, drvNum);
if (err == noErr) err = DIFormat(drvNum);
if (err == noErr) err = DIVerify(drvNum);
if (err == noErr) err = DIZero(drvNum, name);
DoClose(dlg);
SetCursor(&qd.arrow);
FlushEvents(everyEvent,0);
if (err != noErr) {
UnmountVol(nil, drvNum);
Eject(nil, drvNum);
ErrorMessageNumber(kStrFloppyEraseFailed);
continue;
}
}
break;
}
return noErr;
}
/*----------------------------------------------------------------------------
CreateSharedOrLabPrefsFile
Create the initial prefs file in a personal NW folder or on a lab floppy.
Entry: fSpec = pointer to file spec for personal NW folder or floppy disk.
dirID = directory id of personal NW folder or floppy disk.
Exit: function result = error code.
*nwFolderAlias = Handle to alias to personal NW folder or floppy disk.
gPrefsAlias = Handle to alias to prefs file.
----------------------------------------------------------------------------*/
static OSErr CreateSharedOrLabPrefsFile (FSSpec *fSpec, long dirID,
AliasHandle *nwFolderAlias)
{
FSSpec prefs;
OSErr err = noErr;
err = NewAlias(nil, fSpec, nwFolderAlias);
if (err != noErr) return err;
prefs.vRefNum = fSpec->vRefNum;
prefs.parID = dirID;
GetPString(kStrPrefsFileName, prefs.name);
err = MyFSpCreateResFile(&prefs, kNewsWatcherSignature,
kPrefsFileType, smSystemScript);
if (err != noErr) return err;
return NewAlias(nil, &prefs, &gPrefsAlias);
}
/*----------------------------------------------------------------------------
DoNewUserDialog
Present the new user dialog.
Exit: function result = error code.
*nwFolderAlias = nil if private Mac, else handle to alias to
personal NW folder or personal NW floppy disk.
----------------------------------------------------------------------------*/
static OSErr DoNewUserDialog (AliasHandle *nwFolderAlias)
{
DialogPtr dlg = nil;
short item;
StandardFileReply reply;
Str255 string;
AliasHandle alias;
long dirID;
FSSpec fSpec;
OSErr err = noErr;
while (true) {
err = MyGetNewDialog(kNewUserDlg, 0, 0, &dlg);
if (err != noErr) return err;
SetItemKeyEquivalent(dlg, kNewUserPrivateItem, 'P');
SetItemKeyEquivalent(dlg, kNewUserSharedItem, 'S');
SetItemKeyEquivalent(dlg, kNewUserLabItem, 'L');
SetItemKeyEquivalent(dlg, kNewUserQuitItem, 'Q');
if (gDummyPrefsFile) DlgEnableItem(dlg, kNewUserPrivateItem, false);
if (gDummyPrefsLabFile) DlgEnableItem(dlg, kNewUserSharedItem, false);
MyMovableModalDialog(dlg, DialogFilter, &item);
err = DoClose(dlg);
if (err != noErr) return err;
switch (item) {
case kNewUserPrivateItem:
*nwFolderAlias = nil;
return noErr;
case kNewUserSharedItem:
GetPString(kStrPersonalNWFolder, string);
alias = nil;
MakeDefaultFolderAlias(&alias);
MyStandardPutFile(string, "\p", &reply, alias);
MyDisposeHandle(alias);
alias = nil;
if (!reply.sfGood) break;
err = FSpDirCreate(&reply.sfFile, reply.sfScript, &dirID);
if (err != noErr) return err;
return CreateSharedOrLabPrefsFile(&reply.sfFile, dirID, nwFolderAlias);
case kNewUserLabItem:
err = DoGetFloppyDialog(&fSpec.vRefNum, fSpec.name);
if (err == userCanceledErr) break;
if (err != noErr) return err;
fSpec.parID = fsRtParID;
return CreateSharedOrLabPrefsFile(&fSpec, fsRtDirID, nwFolderAlias);
break;
case kNewUserQuitItem:
ExitToShell();
}
}
return noErr;
}
/*----------------------------------------------------------------------------
DoServerDialog
Present the server dialog.
Exit: function result = error code.
gPrefs.newsServerName = news server name.
gPrefs.mailServerName = mail server name.
----------------------------------------------------------------------------*/
static OSErr DoServerDialog (void)
{
DialogPtr dlg = nil;
short item;
Str255 news;
Str255 mail;
OSErr err = noErr;
err = MyGetNewDialog(kServerDlg, ok, cancel, &dlg);
if (err != noErr) return err;
CopyPascalString(news, gPrefs.newsServerName);
DlgSetPString(dlg, kNewsServer, news);
SetItemHostAddress(dlg, kNewsServer);
SetItemMaxLength(dlg, kNewsServer, 255);
CopyPascalString(mail, gPrefs.mailServerName);
DlgSetPString(dlg, kMailServer, mail);
SetItemHostAddress(dlg, kMailServer);
SetItemMaxLength(dlg, kMailServer, 255);
if (*news == 0) {
SelectDialogItemText(dlg, kNewsServer, 0, 0);
} else if (*mail == 0) {
SelectDialogItemText(dlg, kMailServer, 0, 0);
} else {
SelectDialogItemText(dlg, kNewsServer, 0, kMaxShort);
}
do {
DlgEnableItem(dlg, ok, *news != 0 && *mail != 0);
MyMovableModalDialog(dlg, DialogFilter, &item);
switch (item) {
case kNewsServer:
DlgGetPString(dlg, item, news);
break;
case kMailServer:
DlgGetPString(dlg, item, mail);
break;
}
} while (item != ok && item != cancel);
err = DoClose(dlg);
if (err != noErr) return err;
if (item == ok) {
CopyPascalString(gPrefs.newsServerName, news);
CopyPascalString(gPrefs.mailServerName, mail);
MyICWriteSharedPrefs(kICNNTPHost);
MyICWriteSharedPrefs(kICSMTPHost);
}
return item == ok ? noErr : userCanceledErr;
}
/*----------------------------------------------------------------------------
DoPersonalDialog
Present the personal information dialog.
Exit: function result = error code.
gPrefs.fullName = user's full name.
gPrefs.organization = user's organization.
gPrefs.emailAddress = user's email address
----------------------------------------------------------------------------*/
static OSErr DoPersonalDialog (void)
{
DialogPtr dlg = nil;
short item;
CStr255 fullName;
CStr255 organization;
CStr255 address;
OSErr err = noErr;
err = MyGetNewDialog(kPersonalDlg, ok, cancel, &dlg);
if (err != noErr) return err;
strcpy(fullName, gPrefs.fullName);
DlgSetCString(dlg, kFullName, fullName);
SetItemMaxLength(dlg, kFullName, 255);
strcpy(organization, gPrefs.organization);
DlgSetCString(dlg, kOrganization, organization);
SetItemMaxLength(dlg, kOrganization, 255);
strcpy(address, gPrefs.emailAddress);
DlgSetCString(dlg, kAddress, address);
SetItemUSAsciiNoBlank(dlg, kAddress);
SetItemMaxLength(dlg, kAddress, 255);
if (*fullName == 0) {
SelectDialogItemText(dlg, kFullName, 0, 0);
} else if (*organization == 0) {
SelectDialogItemText(dlg, kOrganization, 0, 0);
} else if (*address == 0) {
SelectDialogItemText(dlg, kAddress, 0, 0);
} else {
SelectDialogItemText(dlg, kFullName, 0, kMaxShort);
}
while (true) {
DlgEnableItem(dlg, ok, *address != 0);
MyMovableModalDialog(dlg, DialogFilter, &item);
switch (item) {
case kFullName:
DlgGetCString(dlg, item, fullName);
break;
case kOrganization:
DlgGetCString(dlg, item, organization);
break;
case kAddress:
DlgGetCString(dlg, item, address);
break;
}
if (item == ok) {
if (StringIsValidEmailAddress(address)) {
break;
} else {
StopAlertNumber(kStrBadEmailAddress);
}
} else if (item == cancel) {
break;
}
}
err = DoClose(dlg);
if (err != noErr) return err;
if (item == ok) {
strcpy(gPrefs.fullName, fullName);
strcpy(gPrefs.organization, organization);
strcpy(gPrefs.emailAddress, address);
MyICWriteSharedPrefs(kICRealName);
MyICWriteSharedPrefs(kICOrganization);
MyICWriteSharedPrefs(kICEmail);
}
return item == ok ? noErr : userCanceledErr;
}
/*----------------------------------------------------------------------------
SearchFolderForPrefsFileOrAlias
Search a folder for the preferences file or an alias to the prefs file.
Entry: fSpec = pointer to file spec with vRefNum and parID filled in
for the folder to be searched.
Exit: function result = error code.
= fnfErr if file not found.
*fSpec = file spec of located file in folder.
----------------------------------------------------------------------------*/
static OSErr SearchFolderForPrefsFileOrAlias (FSSpec *fSpec)
{
short index = 1;
OSErr err = noErr;
Str255 oldName, reallyOldName;
FSSpec fSpec2;
FInfo fndrInfo;
GetPString(kStrPrefsFileName, fSpec->name);
err = FSpGetFInfo(fSpec, &fndrInfo);
if (err == noErr && fndrInfo.fdCreator == kNewsWatcherSignature &&
fndrInfo.fdType == kPrefsFileType) return noErr;
err = SearchFolderByCreatorAndType(fSpec, kNewsWatcherSignature,
kPrefsFileType, &index);
if (err != noErr) return err;
GetPString(kStrOldPrefsFileName, oldName);
GetPString(kStrReallyOldPrefsFileName, reallyOldName);
if (EqualString(fSpec->name, oldName, false, true) ||
EqualString(fSpec->name, reallyOldName, false, true))
{
index++;
fSpec2 = *fSpec;
err = SearchFolderByCreatorAndType(&fSpec2, kNewsWatcherSignature,
kPrefsFileType, &index);
if (err == noErr) *fSpec = fSpec2;
}
return noErr;
}
/*----------------------------------------------------------------------------
FindPrefsFileOrAlias
Locate the preferences file or an alias to the prefs file.
Entry: firstEvent = pointer to initial Apple event.
Exit: function result = error code.
= fnfErr if prefs file not found.
*fSpec = location of prefs file or prefs file alias.
----------------------------------------------------------------------------*/
static OSErr FindPrefsFileOrAlias (AppleEvent *firstEvent, FSSpec *fSpec)
{
OSErr err = noErr;
DescType typeCode;
AEEventClass eventClass;
AEEventID eventID;
AEKeyword keywd;
Size actualSize;
AEDescList docList = {0, nil};
DescType returnedType;
long numItems, i;
FInfo fndrInfo;
FSSpec oldFile, prefsFolder;
CInfoPBRec pb;
/* Check to see if NewsWatcher was opened with an ODOC or PDOC event.
If it was, scan the document list and find the first document which
is either a NewsWatcher prefs file or a saved user group list or
message file. If a prefs file is found, use that one. If a saved
document is found, check to see if a prefs file exists in the same
folder and use it if one is found. */
err = AEGetAttributePtr(firstEvent, keyEventClassAttr, typeWildCard,
&typeCode, &eventClass, sizeof(eventClass), &actualSize);
if (err != noErr) goto exit;
if (actualSize == sizeof(eventClass) && eventClass == kCoreEventClass) {
err = AEGetAttributePtr(firstEvent, keyEventIDAttr, typeWildCard,
&typeCode, &eventID, sizeof(eventID), &actualSize);
if (err != noErr) goto exit;
if (actualSize == sizeof(eventID) &&
(eventID == kAEOpenDocuments || eventID == kAEPrintDocuments))
{
err = AEGetParamDesc(firstEvent, keyDirectObject, typeAEList, &docList);
if (err != noErr) goto exit;
err = AECountItems(&docList, &numItems);
if (err != noErr) goto exit;
for (i = 1; i <= numItems; i++) {
err = AEGetNthPtr(&docList, i, typeFSS, &keywd, &returnedType,
(Ptr)fSpec, sizeof(FSSpec), &actualSize);
if (err != noErr) goto exit;
err = FSpGetFInfo(fSpec, &fndrInfo);
if (err != noErr) goto exit;
if (fndrInfo.fdCreator != kNewsWatcherSignature) continue;
if (fndrInfo.fdType == kPrefsFileType) goto exit;
err = SearchFolderForPrefsFileOrAlias(fSpec);
if (err != fnfErr) goto exit;
}
err = AEDisposeDesc(&docList);
if (err != noErr) goto exit;
docList.dataHandle = nil;
}
}
/* Check to see if a prefs file exits in the Preferences folder. */
err = FindFolder(kOnSystemDisk, kPreferencesFolderType,
kCreateFolder, &fSpec->vRefNum, &fSpec->parID);
if (err != noErr) return err;
err = SearchFolderForPrefsFileOrAlias(fSpec);
if (err == noErr) return noErr;
if (err != fnfErr) return err;
/* Check to see if a prefs file exists in the System folder. If it does,
move it to the Preferences folder. */
err = FindFolder(kOnSystemDisk, kSystemFolderType,
kCreateFolder, &oldFile.vRefNum, &oldFile.parID);
if (err != noErr) return err;
err = SearchFolderForPrefsFileOrAlias(&oldFile);
if (err != noErr) return err;
pb.dirInfo.ioNamePtr = prefsFolder.name;
pb.dirInfo.ioVRefNum = fSpec->vRefNum;
pb.dirInfo.ioFDirIndex = -1;
pb.dirInfo.ioDrDirID = fSpec->parID;
err = PBGetCatInfo(&pb, false);
if (err != noErr) return err;
prefsFolder.vRefNum = pb.dirInfo.ioVRefNum;
prefsFolder.parID = pb.dirInfo.ioDrParID;
err = FSpCatMove(&oldFile, &prefsFolder);
if (err != noErr) return err;
CopyPascalString(fSpec->name, oldFile.name);
err = FSpGetFInfo(fSpec, &fndrInfo);
if (err != noErr) return err;
fndrInfo.fdFlags &= ~(1 << 8); /* clear hasBeenInited to force Finder to
assign new icon location */
return FSpSetFInfo(fSpec, &fndrInfo);
exit:
if (docList.dataHandle != nil) AEDisposeDesc(&docList);
return err;
}
/*----------------------------------------------------------------------------
CheckDummyPrefsFile
Check for a dummy prefs file.
Entry: index = index in STR# 128 resource of dummy prefs file name.
Exit: function result = error code.
gDummyPrefsFile = true if dummy prefs file found.
gDummyPrefsLabFile = true if dummy prefs lab file found.
----------------------------------------------------------------------------*/
static OSErr CheckDummyPrefsFile (short index)
{
OSErr err = noErr;
FSSpec fSpec;
FInfo fndrInfo;
short refNum;
long count;
char firstThreeChars[3];
err = FindFolder(kOnSystemDisk, kPreferencesFolderType,
kCreateFolder, &fSpec.vRefNum, &fSpec.parID);
if (err != noErr) return err;
GetPString(index, fSpec.name);
err = FSpGetFInfo(&fSpec, &fndrInfo);
if (err == fnfErr) return noErr;
if (err != noErr) return err;
gDummyPrefsFile = true;
err = FSpOpenDF(&fSpec, fsRdPerm, &refNum);
if (err != noErr) return err;
count = 3;
err = FSRead(refNum, &count, (Ptr)firstThreeChars);
if (err == noErr && count == 3 && MyStrNEqual(firstThreeChars, "lab", 3))
gDummyPrefsLabFile = true;
MyFSClose(refNum, nil);
return noErr;
}
/*----------------------------------------------------------------------------
LocatePrefsFile
Locate the preferences file.
Entry: firstEvent = pointer to initial Apple event.
Exit: function result = error code.
= fnfErr if prefs file not found.
*fSpec = location of prefs file.
*prefsAlias = handle to alias record for located prefs file.
----------------------------------------------------------------------------*/
static OSErr LocatePrefsFile (AppleEvent *firstEvent, FSSpec *fSpec,
AliasHandle *prefsAlias)
{
OSErr err = noErr;
Boolean targetIsFolder, wasAliased;
/* Locate the prefs file or an alias to the prefs file */
err = FindPrefsFileOrAlias(firstEvent, fSpec);
/* Resolve prefs file alias. */
if (err == noErr) {
err = ResolveAliasFile(fSpec, true, &targetIsFolder, &wasAliased);
if (err != noErr) return err;
return NewAlias(nil, fSpec, prefsAlias);
}
/* If prefs file was not found, check to see if there is a dummy prefs
file in the Prefs folder which was created to force users of this Mac
to use a personal prefs file. */
if (err == fnfErr) {
err = CheckDummyPrefsFile(kStrPrefsFileName);
if (err != noErr) return err;
err = CheckDummyPrefsFile(kStrOldPrefsFileName);
if (err != noErr) return err;
err = CheckDummyPrefsFile(kStrReallyOldPrefsFileName);
if (err != noErr) return err;
return fnfErr;
}
return err;
}
/*----------------------------------------------------------------------------
ScramblePW
Scramble (and unscramble) saved passwords. This is not really secure,
just something to foil people browsing using disk editors.
Entry: pw = the password.
len = length of password.
Exit: Each byte nibble-swapped and bit-flipped.
----------------------------------------------------------------------------*/
static void ScramblePW (char *pw, short len)
{
char *p, *pEnd;
pEnd = pw + len;
for (p = pw; p < pEnd; p++) *p = (((*p >> 4) & 0x0f) | ((*p & 0x0f) << 4)) ^ 0xff;
}
/*----------------------------------------------------------------------------
ConstructSavedArtDefaultFolderAlias
In version 2.0d9, we introduced the saved article default folder preference.
The default folder was saved on the prefs file as a volume name and dirID.
In version 2.0d41, we changed this to a saved alias resource.
This function is called if the old prefs file version is >= 2.0d9 and < 2.0d41.
It constructs the new alias from the old volume name and dirID.
----------------------------------------------------------------------------*/
static void ConstructSavedArtDefaultFolderAlias (void)
{
OSErr err = noErr;
CInfoPBRec pBlock;
FSSpec fSpec;
if (gPrefs.savedArtDefaultFolderAlias != nil) {
MyDisposeHandle(gPrefs.savedArtDefaultFolderAlias);
gPrefs.savedArtDefaultFolderAlias = nil;
}
err = VolNameToVRefNum(gPrefs.DefunctSavedArtDefaultVolName, &fSpec.vRefNum);
if (err != noErr) return;
pBlock.dirInfo.ioVRefNum = fSpec.vRefNum;
pBlock.dirInfo.ioDrDirID = gPrefs.DefunctSavedArtDefaultDirID;
pBlock.dirInfo.ioNamePtr = fSpec.name;
pBlock.dirInfo.ioFDirIndex = -1;
err = PBGetCatInfoSync(&pBlock);
if (err != noErr) return;
fSpec.parID = pBlock.dirInfo.ioDrParID;
NewAlias(nil, &fSpec, &gPrefs.savedArtDefaultFolderAlias);
}
/*----------------------------------------------------------------------------
ValidPString
Validate a saved pascal string preference.
Entry: str = pointer to pascal string.
size = size of pascal string.
returnIsLegal = true if return character is legal.
Exit: function result = true if string is valid.
The string is considered to be "valid" if the length byte is less than
the allocated size of the string, and if all the characters in the
string are printable (or carriage returns if returnIsLegal is true).
----------------------------------------------------------------------------*/
Boolean ValidPString (StringPtr str, short size, Boolean returnIsLegal)
{
short len;
len = *(unsigned char*)str;
if (len >= size) return false;
str++;
while (len--) {
if (!isPrintable(*str)) {
if (!returnIsLegal || *str != CR) return false;
}
str++;
}
return true;
}
/*----------------------------------------------------------------------------
ValidCString
Validate a saved C string preference.
Entry: str = pointer to C string.
size = size of C string.
returnIsLegal = true if return character is legal.
Exit: function result = true if string is valid.
The string is considered to be "valid" if it contains a C-format
zero byte terminator and all the characters are printable (or
carriage returns if returnIsLegal is true).
----------------------------------------------------------------------------*/
Boolean ValidCString (char *str, short size, Boolean returnIsLegal)
{
unsigned char *p;
p = (unsigned char*)str;
while (size--) {
if (*p == 0) {
p = (unsigned char*)str;
while (*p != 0) {
if (!isPrintable(*p)) {
if (!returnIsLegal || *p != CR) return false;
}
p++;
}
return true;
}
p++;
}
return false;
}
/*----------------------------------------------------------------------------
PrefsAreValid
Validate saved preferences.
Exit: function result = true if prefs are valid.
This function does some rudimentary sanity checking on the preferences.
----------------------------------------------------------------------------*/
static Boolean PrefsAreValid (void)
{
return
ValidPString(gPrefs.newsServerName, sizeof(gPrefs.newsServerName), false) &&
ValidPString(gPrefs.textFont, sizeof(gPrefs.textFont), false) &&
ValidPString(gPrefs.listFont, sizeof(gPrefs.listFont), false) &&
ValidCString(gPrefs.ftpNewsrcUsername, sizeof(gPrefs.ftpNewsrcUsername), false) &&
ValidCString(gPrefs.ftpNewsrcHost, sizeof(gPrefs.ftpNewsrcHost), false) &&
ValidCString(gPrefs.fullName, sizeof(gPrefs.fullName), false) &&
ValidCString(gPrefs.organization, sizeof(gPrefs.organization), false) &&
ValidCString(gPrefs.signature, sizeof(gPrefs.signature), true) &&
ValidPString(gPrefs.mailServerName, sizeof(gPrefs.mailServerName), false) &&
ValidCString(gPrefs.emailAddress, sizeof(gPrefs.emailAddress), false);
}
/*----------------------------------------------------------------------------
Copy an alias
Entry: a = handle to alias to be copied.
b = pointer to alias handle.
Exit: *b = handle to copy of alias a.
----------------------------------------------------------------------------*/
static void CopyAlias (AliasHandle a, AliasHandle *b)
{
AliasHandle tmpAlias;
OSErr err = noErr;
tmpAlias = a;
err = MyHandToHand(&tmpAlias);
if (err != noErr) return;
*b = tmpAlias;
}
/*----------------------------------------------------------------------------
InitURLHelperInfo
Initialize new version 2.0b25 format URL helper info, converting the
equivalent information from any pre-version 2.0b25 prefs file, if
necessary.
Entry: prefsVersion = old prefs file version number.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr InitURLHelperInfo (unsigned long prefsVersion)
{
OSErr err = noErr;
TURLHelperInfo **h;
MyDisposeHandle(gPrefs.urlHelpers);
err = MyNewHandle(10 * sizeof(TURLHelperInfo), &h);
if (err != noErr) return err;
gPrefs.urlHelpers = h;
strcpy((*h)[0].schemeName, "ftp");
strcpy((*h)[1].schemeName, "http");
strcpy((*h)[2].schemeName, "gopher");
strcpy((*h)[3].schemeName, "wais");
strcpy((*h)[4].schemeName, "telnet");
strcpy((*h)[5].schemeName, "tn3270");
strcpy((*h)[6].schemeName, "finger");
strcpy((*h)[7].schemeName, "whois");
strcpy((*h)[8].schemeName, "ph");
if (prefsVersion >= 0x02006017) {
BlockMoveData(&gPrefs.ftpHelperInfo, &(*h)[0].sig, sizeof(TOldURLHelperInfo));
BlockMoveData(&gPrefs.httpHelperInfo, &(*h)[1].sig, sizeof(TOldURLHelperInfo));
BlockMoveData(&gPrefs.gopherHelperInfo, &(*h)[2].sig, sizeof(TOldURLHelperInfo));
BlockMoveData(&gPrefs.waisHelperInfo, &(*h)[3].sig, sizeof(TOldURLHelperInfo));
BlockMoveData(&gPrefs.telnetHelperInfo, &(*h)[4].sig, sizeof(TOldURLHelperInfo));
BlockMoveData(&gPrefs.tn3270HelperInfo, &(*h)[5].sig, sizeof(TOldURLHelperInfo));
BlockMoveData(&gPrefs.fingerHelperInfo, &(*h)[6].sig, sizeof(TOldURLHelperInfo));
BlockMoveData(&gPrefs.whoisHelperInfo, &(*h)[7].sig, sizeof(TOldURLHelperInfo));
} else if (prefsVersion >= 0x02002025) {
(*h)[0].sig = gPrefs.ftpHelper;
}
if (prefsVersion >= 0x02006023) {
BlockMoveData(&gPrefs.phHelperInfo, &(*h)[8].sig, sizeof(TOldURLHelperInfo));
}
InitDefaultURLHelper("ftp");
InitDefaultURLHelper("http");
InitDefaultURLHelper("gopher");
InitDefaultURLHelper("wais");
InitDefaultURLHelper("telnet");
InitDefaultURLHelper("tn3270");
InitDefaultURLHelper("finger");
InitDefaultURLHelper("whois");
InitDefaultURLHelper("ph");
return noErr;
}
/*----------------------------------------------------------------------------
ReadPrefs
Read the preferences file.
Entry: firstEvent = pointer to initial Apple event.
Exit: function result = error code.
----------------------------------------------------------------------------*/
OSErr ReadPrefs (AppleEvent *firstEvent)
{
OSErr err = noErr;
FSSpec fSpec;
short fRefNum = 0;
long count, size;
unsigned long prefsVersion, progVersion;
CStr255 msg, fmt;
short len;
Handle prefsHandle;
Boolean havePrefs = false, prefsInDataFork = false, prefsDamaged = false;
Boolean prefsFileLocated;
Boolean forceServerDialog = false, forcePersonalDialog = false;
Boolean newUser = false;
DialogPtr dlg = nil;
short item;
AliasHandle nwFolderAlias = nil;
memset(&gPrefs, 0, sizeof(gPrefs));
err = GetVersionNumber(&progVersion);
if (err != noErr) return err;
err = LocatePrefsFile(firstEvent, &fSpec, &gPrefsAlias);
if (err != noErr && err != fnfErr) return err;
prefsFileLocated = err == noErr;
if (prefsFileLocated) {
err = MyFSpOpenResFile(&fSpec, fsRdPerm, &fRefNum);
if (err == noErr) {
err = MyGet1Resource('PREF', 128, &prefsHandle);
if (err == noErr) {
if (MyGetHandleSize(prefsHandle) == sizeof(TPrefRec)) {
havePrefs = true;
BlockMoveData(*prefsHandle, &gPrefs, sizeof(TPrefRec));
gPrefs.savedMsgDefaultFolderAlias = nil;
err = MyGet1Resource(rAliasType, kSavedMsgDefaultFolderAliasID,
&gPrefs.savedMsgDefaultFolderAlias);
if (err == noErr) MyDetachResource(gPrefs.savedMsgDefaultFolderAlias);
gPrefs.savedArtDefaultFolderAlias = nil;
err = MyGet1Resource(rAliasType, kSavedArtDefaultFolderAliasID,
&gPrefs.savedArtDefaultFolderAlias);
if (err == noErr) MyDetachResource(gPrefs.savedArtDefaultFolderAlias);
gPrefs.savedBinDefaultFolderAlias = nil;
err = MyGet1Resource(rAliasType, ksavedBinDefaultFolderAliasID,
&gPrefs.savedBinDefaultFolderAlias);
if (err == noErr) MyDetachResource(gPrefs.savedBinDefaultFolderAlias);
gPrefs.savedUGLDefaultFolderAlias = nil;
err = MyGet1Resource(rAliasType, ksavedUGLDefaultFolderAliasID,
&gPrefs.savedUGLDefaultFolderAlias);
if (err == noErr) MyDetachResource(gPrefs.savedUGLDefaultFolderAlias);
gPrefs.urlHelpers = nil;
err = MyGet1Resource(kURLHelpersType, kURLHelpersID, &gPrefs.urlHelpers);
if (err == noErr) {
MyDetachResource(gPrefs.urlHelpers);
size = MyGetHandleSize(gPrefs.urlHelpers);
if (size == 0 || size % sizeof(TURLHelperInfo) != 0 ||
*(*gPrefs.urlHelpers)[size / sizeof(TURLHelperInfo) - 1].schemeName != 0)
{
MyDisposeHandle(gPrefs.urlHelpers);
gPrefs.urlHelpers = nil;
GetCString(kStrBadURLHelperPrefs, fmt);
p2cstr(fSpec.name);
sprintf(msg, fmt, (char*)fSpec.name);
c2pstr((char*)fSpec.name);
ErrorMessage(msg);
}
}
ReadArticleCache();
} else {
prefsDamaged = true;
}
ReadSavedPageSetupInfoFromPrefs();
}
MyCloseResFile(fRefNum);
}
if (!havePrefs && !prefsDamaged) {
err = FSpOpenDF(&fSpec, fsRdPerm, &fRefNum);
if (err == noErr) {
count = sizeof(TPrefRec);
err = FSRead(fRefNum, &count, (Ptr)&gPrefs);
if (err == noErr && count == sizeof(TPrefRec)) {
havePrefs = true;
prefsInDataFork = true;
gPrefs.savedMsgDefaultFolderAlias = nil;
gPrefs.savedArtDefaultFolderAlias = nil;
gPrefs.savedBinDefaultFolderAlias = nil;
gPrefs.savedUGLDefaultFolderAlias = nil;
gPrefs.urlHelpers = nil;
} else {
prefsDamaged = true;
}
MyFSClose(fRefNum, nil);
} else {
prefsDamaged = true;
}
}
if (prefsDamaged || !havePrefs || !PrefsAreValid()) {
havePrefs = prefsInDataFork = false;
MyDisposeHandle(gPrefs.savedMsgDefaultFolderAlias);
MyDisposeHandle(gPrefs.savedArtDefaultFolderAlias);
MyDisposeHandle(gPrefs.savedBinDefaultFolderAlias);
MyDisposeHandle(gPrefs.savedUGLDefaultFolderAlias);
MyDisposeHandle(gPrefs.urlHelpers);
GetCString(kStrBadPrefs, fmt);
p2cstr(fSpec.name);
sprintf(msg, fmt, (char*)fSpec.name);
c2pstr((char*)fSpec.name);
ErrorMessage(msg);
}
}
if (gPrefs.useInternetConfig) {
if (prefsFileLocated) {
MyICStart(true, fSpec.vRefNum, fSpec.parID);
} else {
MyICStart(false, 0, 0);
}
}
if (havePrefs) gPrefsFileFoundAtStartup = true;
if (!havePrefs) {
newUser = true;
err = DoNewUserDialog(&nwFolderAlias);
if (err != noErr) {
ReportSystemError(err);
ExitToShell();
}
err = MyGet1Resource('PREF', 128, &prefsHandle);
if (err == noErr && MyGetHandleSize(prefsHandle) == sizeof(TPrefRec)) {
BlockMoveData(*prefsHandle, &gPrefs, sizeof(TPrefRec));
havePrefs = true;
gPrefs.savedMsgDefaultFolderAlias = nil;
gPrefs.savedArtDefaultFolderAlias = nil;
gPrefs.savedBinDefaultFolderAlias = nil;
gPrefs.savedUGLDefaultFolderAlias = nil;
gPrefs.urlHelpers = nil;
err = MyGet1Resource(kURLHelpersType, kURLHelpersID, &gPrefs.urlHelpers);
if (err == noErr) MyDetachResource(gPrefs.urlHelpers);
}
if (prefsHandle != nil) MyReleaseResource(prefsHandle);
}
if (!havePrefs) {
prefsVersion = 0x00000000;
memset(&gPrefs, 0, sizeof(gPrefs));
} else if (strcmp(gPrefs.magicCookie, "MagicCookie") != 0) {
prefsVersion = 0x01028000;
} else {
len = strlen(gPrefs.versionString);
if (len == 0) {
prefsVersion = gPrefs.version;
} else if (strcmp(gPrefs.versionString, "1.2(NU)") == 0) {
prefsVersion = 0x01208000;
} else if (len == 5 && strncmp(gPrefs.versionString, "1.3d", 4) == 0) {
prefsVersion = 0x01302000 + gPrefs.versionString[4] - '0';
} else if (len == 5 && strncmp(gPrefs.versionString, "2.0d", 4) == 0) {
prefsVersion = 0x02002000 + gPrefs.versionString[4] - '0';
} else if (len == 6 && strncmp(gPrefs.versionString, "2.0d1", 5) == 0) {
prefsVersion = 0x02002010 + gPrefs.versionString[5] - '0';
} else {
prefsVersion = 0x00000000;
}
}
strcpy(gPrefs.magicCookie, "MagicCookie");
*gPrefs.versionString = 0;
if (progVersion > gPrefs.version) gPrefs.version = progVersion;
ScramblePW(gPrefs.ftpNewsrcPassword, sizeof(gPrefs.ftpNewsrcPassword));
ScramblePW(gPrefs.authPassword, sizeof(gPrefs.authPassword));
if (prefsVersion < 0x01028000) {
*gPrefs.newsServerName = 0;
*gPrefs.mailServerName = 0;
*gPrefs.ftpNewsrcUsername = 0;
*gPrefs.ftpNewsrcHost = 0;
*gPrefs.fullName = 0;
*gPrefs.organization = 0;
*gPrefs.signature = 0;
*gPrefs.emailAddress = 0;
CopyPascalString(gPrefs.listFont, "\pMonaco");
CopyPascalString(gPrefs.textFont, "\pMonaco");
gPrefs.listSize = 9;
gPrefs.textSize = 9;
SetPt(&gPrefs.statusWindowLocn, 0, 0);
gPrefs.fullGroupListVisible = true;
gPrefs.maxFetch = kMaxMaxFetch;
}
if (prefsVersion < 0x01208000) {
gPrefs.areYouSureAlert = true;
}
if (prefsVersion < 0x01302001) {
gPrefs.autoFetchNewsrc = false;
}
if (prefsVersion < 0x01302004) {
gPrefs.showArtHeaders = false;
gPrefs.showAuthors = true;
gPrefs.showThreadsCollapsed = true;
}
if (prefsVersion < 0x02002009) {
gPrefs.checkForNewGroups = true;
gPrefs.groupCheckTime = 0;
memset(gPrefs.ftpNewsrcPassword, 0, sizeof(gPrefs.ftpNewsrcPassword));
gPrefs.saveFtpNewsrcPassword = false;
gPrefs.savedArtCreator = 'ttxt';
GetPString(kStrDefaultTextFileOwner, gPrefs.savedArtAppName);
gPrefs.maxGroupNameWidth = 0;
gPrefs.useXPAT = false;
}
if (prefsVersion < 0x02002010) {
gPrefs.savedArtDefaultFolder = false;
GetCString(kStrDefaultNewsrcFileName, gPrefs.ftpNewsrcPath);
}
if (prefsVersion < 0x02002011) {
gPrefs.addSigSeparatorLine = true;
}
if (prefsVersion < 0x02002012) {
gPrefs.keypadShortcuts = false;
gPrefs.logActionsToFile = false;
}
if (prefsVersion < 0x02002014) {
gPrefs.batchedGroupCmds = false;
gPrefs.noNewConnection = false;
gPrefs.noModeReader = false;
}
if (prefsVersion < 0x02002016) {
gPrefs.reZoomWindows = false;
gPrefs.autoSaveOnQuit = false;
}
if (prefsVersion < 0x02002018) {
gPrefs.replyPost = true;
gPrefs.replyEmail = false;
gPrefs.copySelf = false;
gPrefs.showMsgDetails = false;
gPrefs.tabEnabled = true;
gPrefs.tabStops = 3;
strcpy(gPrefs.quoteString, "> ");
*gPrefs.extraNewsHdrLines = 0;
*gPrefs.extraMailHdrLines = 0;
}
if (prefsVersion < 0x02002019) {
gPrefs.addSigBlankLine = true;
}
if (prefsVersion < 0x02002021) {
SetPt(&gPrefs.prefsLoc, 0, 0);
SetPt(&gPrefs.hostLoc, 0, 0);
SetPt(&gPrefs.servErrLoc, 0, 0);
SetPt(&gPrefs.searchLoc, 0, 0);
SetPt(&gPrefs.delGroupsLoc, 0, 0);
}
if (prefsVersion < 0x02002024) {
gPrefs.wrapOnSend = true;
}
if (prefsVersion < 0x02002026) {
*gPrefs.authUsername = 0;
*gPrefs.authPassword = 0;
gPrefs.authSavePassword = false;
gPrefs.authAtStartup = false;
SetPt(&gPrefs.authLoc, 0, 0);
}
if (prefsVersion < 0x02002027) {
gPrefs.authPrivateGroups = false;
}
if (prefsVersion < 0x02002041) {
gPrefs.savedMsgDefaultFolder = false;
gPrefs.savedMsgDelAfterSend = false;
gPrefsFileWasOldVersion = true;
if (prefsVersion >= 0x02002009) ConstructSavedArtDefaultFolderAlias();
gPrefs.savedBinDefaultFolder = false;
gPrefs.hqxHelper = kExpanderCreatorType;
err = FindAppNameFromSig(kExpanderCreatorType, gPrefs.hqxHelperName);
if (err != noErr) GetPString(kStrHqxDecodeHelperName, gPrefs.hqxHelperName);
} else {
if (*gPrefs.hqxHelperName > 31) *gPrefs.hqxHelperName = 0;
}
if (prefsVersion < 0x02002044) {
gPrefs.uuHelper = kuuUndoCreatorType;
err = FindAppNameFromSig(kuuUndoCreatorType, gPrefs.uuHelperName);
if (err != noErr) GetPString(kStrUUDecodeHelperName, gPrefs.uuHelperName);
gPrefs.keyboardShortcuts = false;
} else {
if (*gPrefs.uuHelperName > 31) *gPrefs.uuHelperName = 0;
}
if (prefsVersion < 0x02002048) {
gPrefs.reuseArticleWinds = false;
}
if (prefsVersion < 0x02006004) {
gPrefs.dontCoverFinderIcons = true;
gPrefs.saveThreadsToSeparateFiles = false;
gPrefs.appendIfFileAlreadyExists = false;
gPrefs.saveEncodedText = false;
gPrefs.subjectWindPosLocked = false;
gPrefs.articleWindPosLocked = false;
if (prefsVersion < 0x01208000) {
gPrefs.fullGroupWindPos.valid = false;
} else {
gPrefs.fullGroupWindPos.valid = true;
gPrefs.fullGroupWindPos.oldFormat = true;
*(Point*)&gPrefs.fullGroupWindPos.userState = gPrefs.fullGroupWindowLocn;
}
if (prefsVersion < 0x02002048) {
gPrefs.autoFetchWindPos.valid = false;
} else {
gPrefs.autoFetchWindPos.valid = true;
gPrefs.autoFetchWindPos.oldFormat = true;
*(Point*)&gPrefs.autoFetchWindPos.userState = gPrefs.autoFetchNewsrcLocn;
}
}
if (prefsVersion < 0x02006012) {
gPrefs.returnToSubjectWindow = true;
}
if (prefsVersion < 0x02006014) {
gPrefs.beepAtEndOfGroup = true;
SetPt(&gPrefs.findLoc, 0, 0);
}
if (prefsVersion < 0x02006015) {
gPrefs.startFindAtBeginning = true;
gPrefs.savedUGLDefaultFolder = false;
SetPt(&gPrefs.waitForDNRLoc, 0, 0);
}
if (prefsVersion < 0x02006021){
CopyPascalString(gPrefs.printingFont, gPrefs.textFont);
gPrefs.printingSize = gPrefs.textSize;
}
if (prefsVersion < 0x02006022) {
gPrefs.useInternetConfig = false;
}
if (prefsVersion < 0x02006023) {
gPrefs.useWebHelperForHtmlFiles = false;
}
if (prefsVersion < 0x02006025) {
SetPt(&gPrefs.retryConnectLoc, 0, 0);
gPrefs.showLabelsUnderIcons = true;
}
if (prefsVersion < 0x02006027) {
if (prefsVersion < 0x02006014) {
gPrefs.stopAtEndOfSubjectList = true;
gPrefs.beepAtEndOfLists = true;
} else {
gPrefs.stopAtEndOfSubjectList = gPrefs.beepAtEndOfLists =
gPrefs.beepAtEndOfGroup;
}
}
if (gPrefs.urlHelpers == nil || prefsVersion < 0x02006025) {
err = InitURLHelperInfo(prefsVersion);
if (err != noErr) return err;
}
if (nwFolderAlias == nil) {
if (gPrefs.savedMsgDefaultFolderAlias == nil)
MakeDefaultFolderAlias(&gPrefs.savedMsgDefaultFolderAlias);
if (gPrefs.savedArtDefaultFolderAlias == nil)
MakeDefaultFolderAlias(&gPrefs.savedArtDefaultFolderAlias);
if (gPrefs.savedBinDefaultFolderAlias == nil)
MakeDefaultFolderAlias(&gPrefs.savedBinDefaultFolderAlias);
if (gPrefs.savedUGLDefaultFolderAlias == nil)
MakeDefaultFolderAlias(&gPrefs.savedUGLDefaultFolderAlias);
} else {
gPrefs.savedUGLDefaultFolderAlias = nwFolderAlias;
gPrefs.savedUGLDefaultFolder = true;
CopyAlias(nwFolderAlias, &gPrefs.savedMsgDefaultFolderAlias);
CopyAlias(nwFolderAlias, &gPrefs.savedArtDefaultFolderAlias);
CopyAlias(nwFolderAlias, &gPrefs.savedBinDefaultFolderAlias);
}
if (prefsVersion < 0x02002026 && prefsVersion > 0) {
err = MyGetNewDialog(kNew20UserAlert, ok, 0, &dlg);
if (err != noErr) return err;
SysBeep(0);
MyModalDialog(dlg, gDialogFilterUPP, &item);
err = DoClose(dlg);
if (err != noErr) return err;
}
if (prefsVersion < 0x02106001 && prefsVersion > 0) {
gPrefs.maxFetch = gPrefs.oldMaxFetch;
if (gPrefs.maxFetch == 15000) gPrefs.maxFetch = kMaxMaxFetch;
}
if (gPrefs.maxFetch <= 0 || gPrefs.maxFetch > kMaxMaxFetch)
gPrefs.maxFetch = kMaxMaxFetch;
if (newUser && nwFolderAlias == nil) {
/* If this a new user who selected the "private" option, use Internet
config to seed the new and mail server addresses and the personal
information preferences. */
if (prefsFileLocated) {
MyICStart(true, fSpec.vRefNum, fSpec.parID);
} else {
MyICStart(false, 0, 0);
}
forceServerDialog = *gPrefs.newsServerName == 0 || *gPrefs.mailServerName == 0;
if (*gPrefs.newsServerName == 0) MyICReadSharedPrefs(kICNNTPHost);
if (*gPrefs.mailServerName == 0) MyICReadSharedPrefs(kICSMTPHost);
forcePersonalDialog = *gPrefs.emailAddress == 0;
if (*gPrefs.fullName == 0) MyICReadSharedPrefs(kICRealName);
if (*gPrefs.organization == 0) MyICReadSharedPrefs(kICOrganization);
if (*gPrefs.emailAddress == 0) MyICReadSharedPrefs(kICEmail);
if (!gPrefs.useInternetConfig) MyICStop();
}
if (forceServerDialog ||
*gPrefs.newsServerName == 0 || *gPrefs.mailServerName == 0)
{
err = DoServerDialog();
if (err != noErr) return err;
}
if (forcePersonalDialog || *gPrefs.emailAddress == 0) {
err = DoPersonalDialog();
if (err != noErr) return err;
}
CopyPascalString(gNewsServerAtStartup, gPrefs.newsServerName);
if (havePrefs && gPrefsAlias != nil) {
err = ReadGroupsFromPrefs(&fSpec, prefsInDataFork, prefsVersion);
if (err != noErr) return err;
}
AdjustExtractBinariesCommand();
return noErr;
}
/*----------------------------------------------------------------------------
WriteGroups
Write the full group list to the preferences file.
Entry: fSpec = pointer to file spec for prefs file.
Exit: function result = error code.
The group names are written as a plain text file, one group name
per line, to the data fork of the prefs file.
----------------------------------------------------------------------------*/
static OSErr WriteGroups (FSSpec *fSpec)
{
OSErr err = noErr;
Ptr groupBuf = nil;
long groupBufNext;
long i;
short len;
char *groupName;
short fRefNum = 0;
Boolean empty;
/* If the user changed news servers, save an empty full group list to force the
program to read a new full group list the next time it is run. */
if (!EqualString(gPrefs.newsServerName, gNewsServerAtStartup, false, true)) {
gNumGroups = 0;
gFullGroupListDirty = true;
}
/* Return if the full group list was not changed since the prefs file was
read at startup. */
if (!gFullGroupListDirty) return noErr;
/* Allocate the group name buffer. */
err = MyNewPtrCritical(10000, &groupBuf);
if (err != noErr) goto exit;
groupBufNext = 0;
/* Open the file. */
err = OpenDataForkWriteCreateIfMissing(fSpec, kNewsWatcherSignature,
kPrefsFileType, smSystemScript, false, &fRefNum, &empty);
if (err != noErr) goto exit;
err = SetEOF(fRefNum, 0);
if (err != noErr) goto exit;
/* Write the group names in order to the file. */
for (i = 0; i < gNumGroups; i++) {
if (groupBufNext + 256 >= 10000) {
err = MyFSWriteNoCache(fRefNum, &groupBufNext, groupBuf, nil);
if (err != noErr) goto exit;
groupBufNext = 0;
}
groupName = *gGroupNames + (*gGroupNameOffsets)[i];
len = strlen(groupName) + 1;
BlockMoveData(groupName, groupBuf + groupBufNext, len);
groupBufNext += len;
*(groupBuf + groupBufNext - 1) = CR;
}
/* Flush the last buffer. */
if (groupBufNext > 0) {
err = MyFSWriteNoCache(fRefNum, &groupBufNext, groupBuf, nil);
if (err != noErr) goto exit;
}
/* Close the file */
MyFSClose(fRefNum, nil);
MyDisposePtr(groupBuf);
return noErr;
exit:
if (fRefNum != 0) MyFSClose(fRefNum, nil);
MyDisposePtr(groupBuf);
return err;
}
/*----------------------------------------------------------------------------
WritePrefs
Write the preferences file.
Exit: function result = error code.
----------------------------------------------------------------------------*/
OSErr WritePrefs (void)
{
OSErr err = noErr;
FSSpec fSpec;
Boolean wasChanged;
short fRefNum = 0;
Handle h, vers = nil;
if (gPrefsAlias != nil) {
err = ResolveAlias(nil, gPrefsAlias, &fSpec, &wasChanged);
if (err != noErr && err != fnfErr) gPrefsAlias = nil;
}
if (gPrefsAlias == nil) {
err = FindFolder(kOnSystemDisk, kPreferencesFolderType,
kCreateFolder, &fSpec.vRefNum, &fSpec.parID);
if (err != noErr) return err;
GetPString(kStrPrefsFileName, fSpec.name);
FSpDelete(&fSpec);
gFullGroupListDirty = true;
} else if (gPrefsFileWasOldVersion) {
FSpDelete(&fSpec);
GetPString(kStrPrefsFileName, fSpec.name);
gFullGroupListDirty = true;
}
if (gFullGroupWindow != nil)
SaveWindPos(gFullGroupWindow, &gPrefs.fullGroupWindPos);
if (!gPrefs.saveFtpNewsrcPassword)
memset(gPrefs.ftpNewsrcPassword, 0, sizeof(gPrefs.ftpNewsrcPassword));
ScramblePW(gPrefs.ftpNewsrcPassword, sizeof(gPrefs.ftpNewsrcPassword));
if (!gPrefs.authSavePassword)
memset(gPrefs.authPassword, 0, sizeof(gPrefs.authPassword));
ScramblePW(gPrefs.authPassword, sizeof(gPrefs.authPassword));
MyGet1Resource('vers', 1, &vers);
if (vers != nil) MyDetachResource(vers);
err = OpenResFileWriteCreateIfMissing(&fSpec, kNewsWatcherSignature,
kPrefsFileType, smSystemScript, &fRefNum);
if (err != noErr) goto exit;
err = MyPtrToHand(&gPrefs, &h, sizeof(TPrefRec));
if (err != noErr) goto exit;
err = MyReplaceResource(h, 'PREF', 128, "\p");
if (err != noErr) goto exit;
if (vers != nil) MyReplaceResource(vers, 'vers', 1, "\p");
err = WriteProgramNameResource(kStrNewsWatcher);
if (err != noErr) goto exit;
if (gPrefs.savedMsgDefaultFolderAlias != nil) {
err = MyReplaceResource(gPrefs.savedMsgDefaultFolderAlias, rAliasType,
kSavedMsgDefaultFolderAliasID, "\p");
if (err != noErr) goto exit;
}
if (gPrefs.savedArtDefaultFolderAlias != nil) {
err = MyReplaceResource(gPrefs.savedArtDefaultFolderAlias, rAliasType,
kSavedArtDefaultFolderAliasID, "\p");
if (err != noErr) goto exit;
}
if (gPrefs.savedBinDefaultFolderAlias != nil) {
err = MyReplaceResource(gPrefs.savedBinDefaultFolderAlias, rAliasType,
ksavedBinDefaultFolderAliasID, "\p");
if (err != noErr) goto exit;
}
if (gPrefs.savedUGLDefaultFolderAlias != nil) {
err = MyReplaceResource(gPrefs.savedUGLDefaultFolderAlias, rAliasType,
ksavedUGLDefaultFolderAliasID, "\p");
if (err != noErr) goto exit;
}
if (gPrefs.urlHelpers != nil) {
err = MyReplaceResource(gPrefs.urlHelpers, kURLHelpersType,
kURLHelpersID, "\p");
if (err != noErr) goto exit;
}
err = WriteArticleCache(gNewsServerAtStartup);
if (err != noErr) goto exit;
WritePageSetupInfoToPrefs();
MyCloseResFile(fRefNum);
err = WriteGroups(&fSpec);
if (err != noErr) goto exit;
return noErr;
exit:
if (fRefNum != 0) MyCloseResFile(fRefNum);
return err;
}